package com.woniuxy.yoga.course.service.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.woniuxy.yoga.coach.dao.model.Coach;
import com.woniuxy.yoga.commons.core.model.PageInfo;
import com.woniuxy.yoga.commons.core.model.Result;
import com.woniuxy.yoga.commons.core.statedata.BusinessState;
import com.woniuxy.yoga.commons.core.statedata.CoachState;
import com.woniuxy.yoga.commons.core.statedata.CourseState;
import com.woniuxy.yoga.commons.core.statedata.ProductState;
import com.woniuxy.yoga.commons.core.util.DateUtil;
import com.woniuxy.yoga.commons.redis.util.rediskeyutil.CourseRedisKeyUtil;
import com.woniuxy.yoga.course.client.BusinessClient;
import com.woniuxy.yoga.course.client.CoachClient;
import com.woniuxy.yoga.course.client.CourseClient;
import com.woniuxy.yoga.course.client.ProductClient;
import com.woniuxy.yoga.course.client.dto.business.BusinessStoreDTO;
import com.woniuxy.yoga.course.client.dto.business.StoreClassroomByIdDTO;
import com.woniuxy.yoga.course.client.dto.course.CourseTypeDTO;
import com.woniuxy.yoga.course.client.dto.product.AllTeamProductDTO;
import com.woniuxy.yoga.course.dao.model.OrdinaryCourse;
import com.woniuxy.yoga.course.dao.mapper.OrdinaryCourseMapper;
import com.woniuxy.yoga.course.model.dto.ordinary.*;
import com.woniuxy.yoga.course.model.exception.CourseException;
import com.woniuxy.yoga.course.model.exception.CourseExceptionCode;
import com.woniuxy.yoga.course.model.param.ordinary.*;
import com.woniuxy.yoga.course.service.service.OrdinaryCourseService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import io.seata.spring.annotation.GlobalTransactional;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * <p>
 * 普通课程表 服务实现类
 * </p>
 *
 * @author 韦用文,刘存益,郎腾霄
 * @since 2023年11月28日
 */
@Service
public class OrdinaryCourseServiceImpl extends ServiceImpl<OrdinaryCourseMapper, OrdinaryCourse> implements OrdinaryCourseService {

    @Autowired
    private OrdinaryCourseMapper ordinaryCourseMapper;

    @Autowired
    private CourseClient courseClient;

    @Autowired
    private CoachClient coachClient;

    @Autowired
    private BusinessClient businessClient;

    @Autowired
    private ProductClient productClient;

    @Autowired
    private RedissonClient redissonClient;

    /**
     * 教练ID查询普通课程信息
     * @param ids
     * @return
     */
    @Override
    public List<OrdinaryCourseDTO> getByCoachId(List<Integer> ids) {
        QueryWrapper<OrdinaryCourse> wrapper = new QueryWrapper<>();
        wrapper.eq("coach_id",ids.get(0));
        //索引排序
        wrapper.orderByAsc("course_id");
        //获取数据
        List<OrdinaryCourse> ordinaryCourses = ordinaryCourseMapper.selectList(wrapper);
        //数据转换
        List<OrdinaryCourseDTO> ordinaryCourseDTOS = BeanUtil.copyToList(ordinaryCourses, OrdinaryCourseDTO.class);
        return ordinaryCourseDTOS;
    }

    /**
     * 新增普通课程
     * @param param
     */
    @Override
    @GlobalTransactional(rollbackFor = Exception.class)
    public void addOrdinaryCourse(AddOrdinaryCourseParam param) {
        //获取开始时间
        LocalDateTime localStartDate = DateUtil.StringToLocalDateTime(param.getCourseStartDate());
        Date startDate = DateUtil.localDateTimeToDate(localStartDate);
        long startTime = startDate.getTime();
        //获取结束时间
        LocalDateTime localEndDate = DateUtil.StringToLocalDateTime(param.getCourseEndDate());
        Date endDate = DateUtil.localDateTimeToDate(localEndDate);
        long endTime = endDate.getTime();
        //判断时间是否是未来的时间
        long currentTime = new Date().getTime();
        if (startTime<=currentTime) throw new CourseException(CourseExceptionCode.COURSE_EXCEPTION_CODE_ORDINARY_COURSE_TIME_ERROR);
        //判断开始时间是否大于等于结束时间
        if (startTime>endTime) throw new CourseException(CourseExceptionCode.COURSE_EXCEPTION_CODE_ORDINARY_COURSE_TIME_ERROR);
        //判断教练是否报错
        Result<Coach> coachResult = coachClient.getCoachById(param.getCoachId());
        if (coachResult.getCode()!=200) throw new CourseException(coachResult.getCode(),coachResult.getMessage());
        //获取数据
        Coach coach = coachResult.getData();
        //判断是否存在
        if (coach==null) throw new CourseException(CourseExceptionCode.COURSE_EXCEPTION_CODE_COACH_NOT_EXIST);
        //判断教练状态是否异常
        if (coach.getCoachState()!= CoachState.COACH_STATE_NORMAL) throw new CourseException(CourseExceptionCode.COURSE_EXCEPTION_CODE_COACH_STATE_ERROR);
        //将传过来的开始时间拼接
        String courseStartDate = param.getCourseStartDate();
        long courseStartTime = DateUtil.convertToMilliseconds(courseStartDate);
        //将传过来的结束时间拼接
        String courseEndDate = param.getCourseEndDate();
        long courseEndTime = DateUtil.convertToMilliseconds(courseEndDate);
        //查询该教练的所有普通课程 判断时间是否存在重复 需要注意课程状态
        List<Integer> ids = new ArrayList<>();
        ids.add(coach.getCoachId());
        List<OrdinaryCourseDTO> ordinaryCourseDTOS = this.getByCoachId(ids);
        if (ordinaryCourseDTOS!=null&&ordinaryCourseDTOS.size()>0){
            //遍历该教练的所有普通课程
            for (OrdinaryCourseDTO ordinaryCourseDTO : ordinaryCourseDTOS) {
                //判断普通课程状态是否是待开课和已开课
                if (ordinaryCourseDTO.getCourseState()==CourseState.ORDINARY_COURSE_STATE_WAIT||ordinaryCourseDTO.getCourseState()==CourseState.ORDINARY_COURSE_STATE_START){
                    //获取课程的开始时间
                    String start = ordinaryCourseDTO.getCourseStartDate();
                    long startDateTime = DateUtil.convertToMilliseconds(start);
                    //获取课程的结束时间
                    String end = ordinaryCourseDTO.getCourseEndDate();
                    long endDateTime = DateUtil.convertToMilliseconds(end);
                    //判断新增的课程时间是否包含该课程时间
                    if (!((startDateTime<courseStartTime&&endDateTime<courseStartTime) || (startDateTime>courseEndTime&&endDateTime>courseEndTime))){
                        //包含 该教练时间冲突
                        throw new CourseException(CourseExceptionCode.COURSE_EXCEPTION_CODE_COACH_TIME_CONFLICT);
                    }
                }
            }
        }
        //查询该教练的所有团队产品 判断时间是否存在重复 需要注意产品状态
        Result<List<AllTeamProductDTO>> allTeamProductDTOResult = productClient.getProductByCoachId(ids);
        if (allTeamProductDTOResult.getCode()!=200) throw new CourseException(allTeamProductDTOResult.getCode(),allTeamProductDTOResult.getMessage());
        //获取数据
        List<AllTeamProductDTO> allTeamProductDTOS = allTeamProductDTOResult.getData();
        //判断是否存在
        if (allTeamProductDTOS!=null&&allTeamProductDTOS.size()>0){
            //遍历该教练的所有团队产品
            for (AllTeamProductDTO allTeamProductDTO : allTeamProductDTOS) {
                //判断团队产品状态是否是待开课或者已开课
                if (allTeamProductDTO.getTeamProductState() == ProductState.TEAM_PRODUCT_STATE_WAIT||allTeamProductDTO.getTeamProductState()== ProductState.TEAM_PRODUCT_STATE_START){
                    //获取课程的开始时间
                    String openTime = allTeamProductDTO.getOpenTime();
                    long open = DateUtil.convertToMilliseconds(openTime);
                    //通过天数计算出结束时间 加两个小时
                    String finalTime = DateUtil.addDaysToString(allTeamProductDTO.getOpenTime(), allTeamProductDTO.getHourCount()-1);
                    String teamEndTime = DateUtil.increaseTwoHour(finalTime);
                    long end = DateUtil.convertToMilliseconds(teamEndTime);
                    //判断新增的课程时间是否包含该课程时间
                    if (!( (open<courseStartTime&&end<courseStartTime) || (open>courseEndTime&&end>courseEndTime) )){
                        //包含 该教练时间冲突
                        throw new CourseException(CourseExceptionCode.COURSE_EXCEPTION_CODE_COACH_TIME_CONFLICT);
                    }
                }
            }
        }
        //判断课程时长是否充足
        if (param.getCourseDuration()<2) throw new CourseException(CourseExceptionCode.COURSE_EXCEPTION_CODE_COURSE_TIME_DELETION);
        //判断场馆是否报错
        Result<BusinessStoreDTO> businessStoreDTOResult = businessClient.selByBusinessStoreId(param.getStoreId());
        if (businessStoreDTOResult.getCode()!=200) throw new CourseException(businessStoreDTOResult.getCode(),businessStoreDTOResult.getMessage());
        //获取数据
        BusinessStoreDTO businessStoreDTO = businessStoreDTOResult.getData();
        //判断是否存在
        if (businessStoreDTO==null) throw new CourseException(CourseExceptionCode.COURSE_EXCEPTION_CODE_BUSINESS_STORE_NOT_EXIST);
        //判断场馆状态是否异常
        if (businessStoreDTO.getStoreState()== BusinessState.STORE_STATE_DELETE) throw new CourseException(CourseExceptionCode.COURSE_EXCEPTION_CODE_BUSINESS_STORE_STATE_ERROR);
        //判断教室是否报错
        Result<StoreClassroomByIdDTO> storeClassroomByIdDTOResult = businessClient.selNormalByStoreClassroomId(param.getClassroomId());
        if (storeClassroomByIdDTOResult.getCode()!=200) throw new CourseException(storeClassroomByIdDTOResult.getCode(),storeClassroomByIdDTOResult.getMessage());
        //获取数据
        StoreClassroomByIdDTO storeClassroomByIdDTO = storeClassroomByIdDTOResult.getData();
        //判断是否存在
        if (storeClassroomByIdDTO==null) throw new CourseException(CourseExceptionCode.COURSE_EXCEPTION_CODE_CLASS_ROOM_NOT_EXIST);
        //判断状态是否异常
        if (storeClassroomByIdDTO.getClassroomState()!=BusinessState.CLASSROOM_STATE_NORMAL) throw new CourseException(CourseExceptionCode.COURSE_EXCEPTION_CODE_CLASS_ROOM_STATE_ERROR);
        //判断普通课程最大人数是否大于教室最大人数
        if (param.getMaxCount()>storeClassroomByIdDTO.getClassroomMax()) throw new CourseException(CourseExceptionCode.COURSE_EXCEPTION_CODE_MAX_COUNT_NOT_GT_CLASS_MAX_COUNT);
        //判断是否是团课教室
        if (storeClassroomByIdDTO.getClassroomType()==1) throw new CourseException(CourseExceptionCode.COURSE_EXCEPTION_CODE_CLASS_ROOM_IS_TEAM_CLASS_ROOM);
        //判断该教室在普通课程该时间段是否已经被占用
        List<OrdinaryCourseDTO> courseDTOList = this.getByClassroomId(storeClassroomByIdDTO.getClassroomId());
        //判断是否存在
        if (courseDTOList!=null&&courseDTOList.size()>0){
            //遍历判断
            for (OrdinaryCourseDTO ordinaryCourseDTO : courseDTOList) {
                //判断是否存在待开课和已开课的普通课程
                if (ordinaryCourseDTO.getCourseState()==CourseState.ORDINARY_COURSE_STATE_WAIT || ordinaryCourseDTO.getCourseState()==CourseState.ORDINARY_COURSE_STATE_START){
                    //获取开始时间
                    String start = ordinaryCourseDTO.getCourseStartDate();
                    long startDateTime = DateUtil.convertToMilliseconds(start);
                    //获取结束时间
                    String end = ordinaryCourseDTO.getCourseEndDate();
                    long endDateTime = DateUtil.convertToMilliseconds(end);
                    //判断新增的课程时间是否包含该课程时间
                    if (!((startDateTime<courseStartTime&&endDateTime<courseStartTime) || (startDateTime>courseEndTime&&endDateTime>courseEndTime))){
                        //存在 普通课程已经存在占用该教室
                        throw new CourseException(CourseExceptionCode.COURSE_EXCEPTION_CODE_CLASS_ROOM_TIME_CONFLICT);
                    }
                }
            }
        }
        //判断教练是否属于该场馆
        if (coach.getStoreId()!=param.getStoreId()) throw new CourseException(CourseExceptionCode.COURSE_EXCEPTION_CODE_COACH_NOT_BELONG_STORE);
        //判断教室是否属于该场馆
        if (storeClassroomByIdDTO.getStoreId()!=param.getStoreId()) throw new CourseException(CourseExceptionCode.COURSE_EXCEPTION_CODE_CLASS_ROOM_NOT_BELONG_STORE);
        //计算两个时间之间的天数
        Integer day = DateUtil.stringDateTime2Days(param.getCourseStartDate(), param.getCourseEndDate());
        //循环遍历
        for (int i = 0; i < day+1; i++) {
            //对象转换
            OrdinaryCourse ordinaryCourse = BeanUtil.toBean(param, OrdinaryCourse.class);
            //每循环一次就加一天时间
            String newCourseTime = DateUtil.addDaysToString(courseStartDate,i);
            //时间赋值
            ordinaryCourse.setCourseStartDate(newCourseTime);
            ordinaryCourse.setCourseEndDate(DateUtil.increaseTwoHour(newCourseTime));
            //状态设置为待开课
            ordinaryCourse.setCourseState(CourseState.ORDINARY_COURSE_STATE_WAIT);
            //课程类型ID赋值
            ordinaryCourse.setCourseTypeId(CourseState.ORDINARY_COURSE_TYPE_ID);
            //教练介绍赋值
            ordinaryCourse.setCoachIntroduce(coach.getCoachIntroduce());
            //添加数据
            ordinaryCourseMapper.insert(ordinaryCourse);
        }
    }

    /**
     * 普通课程开课
     * @param courseId
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void startOrdinaryCourse(Integer courseId) {
        OrdinaryCourse ordinaryCourse = ordinaryCourseMapper.selectById(courseId);
        //判断是否存在
        if (ordinaryCourse==null) throw new CourseException(CourseExceptionCode.COURSE_EXCEPTION_CODE_ORDINARY_COURSE_NOT_EXIST);
        //判断普通课程状态是否异常
        if (ordinaryCourse.getCourseState()!=CourseState.ORDINARY_COURSE_STATE_WAIT) throw new CourseException(CourseExceptionCode.COURSE_EXCEPTION_CODE_ORDINARY_COURSE_STATE_ERROR);
        //获取开课时间
        long startTime = DateUtil.convertToMilliseconds(ordinaryCourse.getCourseStartDate());
        //获取结束时间
        long endTime = DateUtil.convertToMilliseconds(ordinaryCourse.getCourseEndDate());
        //获取当前时间
        long currentTime = new Date().getTime();
        //判断当前时间是否在开课时间和结束时间之间
        if (currentTime<startTime || currentTime>endTime) throw new CourseException(CourseExceptionCode.COURSE_EXCEPTION_CODE_CURRENT_TIME_NOT_COURSE);
        //修改普通课程状态为已开课
        ordinaryCourse.setCourseState(CourseState.ORDINARY_COURSE_STATE_START);
        ordinaryCourseMapper.updateById(ordinaryCourse);
    }

    /**
     * 普通课程取消(取消不用判断时间)
     * @param courseId
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void cancelOrdinaryCourse(Integer courseId) {
        OrdinaryCourse ordinaryCourse = ordinaryCourseMapper.selectById(courseId);
        //判断是否存在
        if (ordinaryCourse==null) throw new CourseException(CourseExceptionCode.COURSE_EXCEPTION_CODE_ORDINARY_COURSE_NOT_EXIST);
        //判断普通课程状态是否异常
        if (ordinaryCourse.getCourseState()!=CourseState.ORDINARY_COURSE_STATE_WAIT) throw new CourseException(CourseExceptionCode.COURSE_EXCEPTION_CODE_ORDINARY_COURSE_STATE_ERROR);
        //修改普通课程状态为已取消
        ordinaryCourse.setCourseState(CourseState.ORDINARY_COURSE_STATE_CANCEL);
        ordinaryCourseMapper.updateById(ordinaryCourse);
    }

    /**
     * 普通课程完成
     * @param courseId
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void completeOrdinaryCourse(Integer courseId) {
        OrdinaryCourse ordinaryCourse = ordinaryCourseMapper.selectById(courseId);
        //判断是否存在
        if (ordinaryCourse==null) throw new CourseException(CourseExceptionCode.COURSE_EXCEPTION_CODE_ORDINARY_COURSE_NOT_EXIST);
        //判断普通课程状态是否异常
        if (ordinaryCourse.getCourseState()!=CourseState.ORDINARY_COURSE_STATE_START) throw new CourseException(CourseExceptionCode.COURSE_EXCEPTION_CODE_ORDINARY_COURSE_STATE_ERROR);
        //获取结束时间
        long endTime = DateUtil.convertToMilliseconds(ordinaryCourse.getCourseEndDate());
        //获取当前时间
        long currentTime = new Date().getTime();
        //判断当前时间是否在结束时间之后
        if (currentTime<endTime) throw new CourseException(CourseExceptionCode.COURSE_EXCEPTION_CODE_CURRENT_TIME_NOT_CLASS);
        //修改普通课程状态为已完成
        ordinaryCourse.setCourseState(CourseState.ORDINARY_COURSE_STATE_COMPLETE);
        ordinaryCourseMapper.updateById(ordinaryCourse);
    }

    /**
     * 普通课程当前人数加一
     * @param courseId
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void increaseCurrentCount(Integer courseId) throws Exception {
        //创建单锁
        RLock lock = redissonClient.getFairLock(CourseRedisKeyUtil.lockCurrentCountByCourseId(courseId));
        boolean isLock = lock.tryLock(10, TimeUnit.SECONDS);
        try {
            if (!isLock){
                throw new Exception("服务器繁忙请稍后再试");
            }
            OrdinaryCourse ordinaryCourse = ordinaryCourseMapper.selectById(courseId);
            //判断是否存在
            if (ordinaryCourse==null) throw new CourseException(CourseExceptionCode.COURSE_EXCEPTION_CODE_ORDINARY_COURSE_NOT_EXIST);
            //判断普通课程状态是否异常
            if (ordinaryCourse.getCourseState()!=CourseState.ORDINARY_COURSE_STATE_WAIT) throw new CourseException(CourseExceptionCode.COURSE_EXCEPTION_CODE_ORDINARY_COURSE_STATE_ERROR);
            //判断当前人数是否等于最大人数
            if (ordinaryCourse.getCurrentCount()>=ordinaryCourse.getMaxCount()) throw new CourseException(CourseExceptionCode.COURSE_EXCEPTION_CODE_CURRENT_NUM_CROWN);
            //当前人数加一
            ordinaryCourse.setCurrentCount(ordinaryCourse.getCurrentCount()+1);
            ordinaryCourseMapper.updateById(ordinaryCourse);
        }finally {
            //判断是否是自己的锁 并且还未释放
            if (lock.isLocked()){
                lock.unlock();
            }
        }
    }

    /**
     * 教室ID查询普通课程
     * @param classroomId
     * @return
     */
    @Override
    public List<OrdinaryCourseDTO> getByClassroomId(Integer classroomId) {
        QueryWrapper<OrdinaryCourse> wrapper = new QueryWrapper<>();
        wrapper.eq("classroom_id",classroomId);
        //索引排序
        wrapper.orderByAsc("course_id");
        //获取数据
        List<OrdinaryCourse> ordinaryCourses = ordinaryCourseMapper.selectList(wrapper);
        //集合转换
        List<OrdinaryCourseDTO> ordinaryCourseDTOS = BeanUtil.copyToList(ordinaryCourses, OrdinaryCourseDTO.class);
        //返回数据
        return ordinaryCourseDTOS;
    }

    /**
     * 查询正常的普通课程
     * @param param
     * @return
     */
    @Override
    public PageInfo queryNormalOrdinaryCourse(QueryNormalOrdinaryCourseParam param) {
        QueryWrapper<OrdinaryCourse> wrapper = new QueryWrapper<>();
        //待开课的课程
        wrapper.eq("course_state",CourseState.ORDINARY_COURSE_STATE_WAIT);
        //开始时间搜索
        if (ObjectUtil.isNotEmpty(param.getCourseStartDate())){
            wrapper.ge("course_start_date",param.getCourseStartDate());
        }
        //结束时间搜索
        if (ObjectUtil.isNotEmpty(param.getCourseEndDate())){
            wrapper.le("course_end_date",param.getCourseEndDate());
        }
        //课程类型ID搜索
        if (ObjectUtil.isNotEmpty(param.getCourseTypeId())){
            wrapper.eq("course_type_id",param.getCourseTypeId());
        }
        //索引排序
        wrapper.orderByAsc("course_id");
        //分页查询
        Page<OrdinaryCourse> page = new Page<>(param.getPageNum() == null ? 1 : param.getPageNum(), param.getPageSize() == null ? 5 : param.getPageSize());
        ordinaryCourseMapper.selectPage(page,wrapper);
        //数据转换
        List<NormalOrdinaryCourseDTO> normalOrdinaryCourseDTOS = new ArrayList<>();
        if (page.getRecords()!=null&&page.getRecords().size()>0){
            for (OrdinaryCourse ordinaryCourse : page.getRecords()) {
                //对象转换
                NormalOrdinaryCourseDTO normalOrdinaryCourseDTO = BeanUtil.toBean(ordinaryCourse, NormalOrdinaryCourseDTO.class);
                //课程类型赋值
                Result<CourseTypeDTO> courseTypeDTOResult = courseClient.getCourseTypeById(ordinaryCourse.getCourseTypeId());
                if (courseTypeDTOResult.getCode()!=200) throw new CourseException(courseTypeDTOResult.getCode(),courseTypeDTOResult.getMessage());
                //获取数据
                CourseTypeDTO courseTypeDTO = courseTypeDTOResult.getData();
                //判断是否存在
                if (courseTypeDTO==null) throw new CourseException(CourseExceptionCode.COURSE_EXCEPTION_CODE_COURSE_TYPE_NOT_EXIST);
                normalOrdinaryCourseDTO.setCourseTypeName(courseTypeDTO.getCourseTypeName());
                //教练名称赋值
                Result<Coach> coachResult = coachClient.getCoachById(ordinaryCourse.getCoachId());
                if (coachResult.getCode()!=200) throw new CourseException(coachResult.getCode(),coachResult.getMessage());
                //获取数据
                Coach coach = coachResult.getData();
                //判断是否存在
                if (coach==null) throw new CourseException(CourseExceptionCode.COURSE_EXCEPTION_CODE_COACH_NOT_EXIST);
                normalOrdinaryCourseDTO.setCoachName(coach.getCoachName());
                //门店名称赋值
                Result<BusinessStoreDTO> businessStoreDTOResult = businessClient.selByBusinessStoreId(ordinaryCourse.getStoreId());
                if (businessStoreDTOResult.getCode()!=200) throw new CourseException(businessStoreDTOResult.getCode(),businessStoreDTOResult.getMessage());
                //获取数据
                BusinessStoreDTO businessStoreDTO = businessStoreDTOResult.getData();
                normalOrdinaryCourseDTO.setStoreName(businessStoreDTO.getStoreName());
                //教室名称赋值
                Result<StoreClassroomByIdDTO> storeClassroomByIdDTOResult = businessClient.selNormalByStoreClassroomId(ordinaryCourse.getClassroomId());
                if (storeClassroomByIdDTOResult.getCode()!=200) throw new CourseException(storeClassroomByIdDTOResult.getCode(),storeClassroomByIdDTOResult.getMessage());
                //获取数据
                StoreClassroomByIdDTO storeClassroomByIdDTO = storeClassroomByIdDTOResult.getData();
                //判断是否存在
                if (storeClassroomByIdDTO==null) throw new CourseException(CourseExceptionCode.COURSE_EXCEPTION_CODE_CLASS_ROOM_NOT_EXIST);
                normalOrdinaryCourseDTO.setClassroomName(storeClassroomByIdDTO.getClassroomName());
                //状态赋值
                normalOrdinaryCourseDTO.setCourseState(ordinaryCourse.getCourseState()==0?"待开课":ordinaryCourse.getCourseState()==1?"已开课":ordinaryCourse.getCourseState()==2?"已取消":"已完成");
                //数据保存
                normalOrdinaryCourseDTOS.add(normalOrdinaryCourseDTO);
            }
        }
        //分页对象转换
        PageInfo pageInfo = BeanUtil.toBean(page, PageInfo.class);
        pageInfo.setPages(page.getPages());
        pageInfo.setRecords(normalOrdinaryCourseDTOS);
        return pageInfo;
    }

    /**
     * 商家查询所有的普通课程
     * @param param
     * @return
     */
    @Override
    public PageInfo queryAllOrdinaryCourse(QueryAllOrdinaryCourseParam param) {
        QueryWrapper<OrdinaryCourse> wrapper = new QueryWrapper<>();
        //开始时间搜索
        if (ObjectUtil.isNotEmpty(param.getCourseStartDate())){
            wrapper.ge("course_start_date",param.getCourseStartDate());
        }
        //结束时间搜索
        if (ObjectUtil.isNotEmpty(param.getCourseEndDate())){
            wrapper.le("course_end_date",param.getCourseEndDate());
        }
        //课程类型ID搜索
        if (ObjectUtil.isNotEmpty(param.getCourseTypeId())){
            wrapper.eq("course_type_id",param.getCourseTypeId());
        }
        //状态搜索
        if (ObjectUtil.isNotEmpty(param.getCourseState())){
            wrapper.eq("course_state",param.getCourseState());
        }
        //绑定门店
        wrapper.eq("store_id",param.getStoreId());
        //索引排序
        wrapper.orderByAsc("course_id");
        //分页查询
        Page<OrdinaryCourse> page = new Page<>(param.getPageNum() == null ? 1 : param.getPageNum(), param.getPageSize() == null ? 5 : param.getPageSize());
        ordinaryCourseMapper.selectPage(page,wrapper);
        //集合转换
        List<AllOrdinaryCourseDTO> allOrdinaryCourseDTOS = new ArrayList<>();
        if (page.getRecords()!=null&&page.getRecords().size()>0){
            for (OrdinaryCourse ordinaryCourse : page.getRecords()) {
                //对象转换
                AllOrdinaryCourseDTO allOrdinaryCourseDTO = BeanUtil.toBean(ordinaryCourse, AllOrdinaryCourseDTO.class);
                //课程类型赋值
                Result<CourseTypeDTO> courseTypeDTOResult = courseClient.getCourseTypeById(ordinaryCourse.getCourseTypeId());
                if (courseTypeDTOResult.getCode()!=200) throw new CourseException(courseTypeDTOResult.getCode(),courseTypeDTOResult.getMessage());
                //获取数据
                CourseTypeDTO courseTypeDTO = courseTypeDTOResult.getData();
                //判断是否存在
                if (courseTypeDTO==null) throw new CourseException(CourseExceptionCode.COURSE_EXCEPTION_CODE_COURSE_TYPE_NOT_EXIST);
                allOrdinaryCourseDTO.setCourseTypeName(courseTypeDTO.getCourseTypeName());
                //教练名称赋值
                Result<Coach> coachResult = coachClient.getCoachById(ordinaryCourse.getCoachId());
                if (coachResult.getCode()!=200) throw new CourseException(coachResult.getCode(),coachResult.getMessage());
                //获取数据
                Coach coach = coachResult.getData();
                //判断是否存在
                if (coach==null) throw new CourseException(CourseExceptionCode.COURSE_EXCEPTION_CODE_COACH_NOT_EXIST);
                allOrdinaryCourseDTO.setCoachName(coach.getCoachName());
                //门店名称赋值
                Result<BusinessStoreDTO> businessStoreDTOResult = businessClient.selByBusinessStoreId(ordinaryCourse.getStoreId());
                if (businessStoreDTOResult.getCode()!=200) throw new CourseException(businessStoreDTOResult.getCode(),businessStoreDTOResult.getMessage());
                //获取数据
                BusinessStoreDTO businessStoreDTO = businessStoreDTOResult.getData();
                allOrdinaryCourseDTO.setStoreName(businessStoreDTO.getStoreName());
                //教室名称赋值
                Result<StoreClassroomByIdDTO> storeClassroomByIdDTOResult = businessClient.selNormalByStoreClassroomId(ordinaryCourse.getClassroomId());
                if (storeClassroomByIdDTOResult.getCode()!=200) throw new CourseException(storeClassroomByIdDTOResult.getCode(),storeClassroomByIdDTOResult.getMessage());
                //获取数据
                StoreClassroomByIdDTO storeClassroomByIdDTO = storeClassroomByIdDTOResult.getData();
                //判断是否存在
                if (storeClassroomByIdDTO==null) throw new CourseException(CourseExceptionCode.COURSE_EXCEPTION_CODE_CLASS_ROOM_NOT_EXIST);
                allOrdinaryCourseDTO.setClassroomName(storeClassroomByIdDTO.getClassroomName());
                //状态赋值
                allOrdinaryCourseDTO.setCourseState(ordinaryCourse.getCourseState()==0?"待开课":ordinaryCourse.getCourseState()==1?"已开课":ordinaryCourse.getCourseState()==2?"已取消":"已完成");
                //数据保存
                allOrdinaryCourseDTOS.add(allOrdinaryCourseDTO);
            }
        }
        //分页对象转换
        PageInfo pageInfo = BeanUtil.toBean(page, PageInfo.class);
        pageInfo.setPages(page.getPages());
        pageInfo.setRecords(allOrdinaryCourseDTOS);
        return pageInfo;
    }

    /**
     * 教练查询自己的普通课程
     * @param param
     * @return
     */
    @Override
    public PageInfo queryCoachOrdinaryCourse(QueryCoachOrdinaryCourseParam param) {
        QueryWrapper<OrdinaryCourse> wrapper = new QueryWrapper<>();
        wrapper.eq("coach_id",param.getCoachId());
        //开始时间搜索
        if (ObjectUtil.isNotEmpty(param.getCourseStartDate())){
            wrapper.ge("course_start_date",param.getCourseStartDate());
        }
        //结束时间搜索
        if (ObjectUtil.isNotEmpty(param.getCourseEndDate())){
            wrapper.le("course_end_date",param.getCourseEndDate());
        }
        //课程类型ID搜索
        if (ObjectUtil.isNotEmpty(param.getCourseTypeId())){
            wrapper.eq("course_type_id",param.getCourseTypeId());
        }
        //状态搜索
        if (ObjectUtil.isNotEmpty(param.getCourseState())){
            wrapper.eq("course_state",param.getCourseState());
        }
        //索引排序
        wrapper.orderByAsc("course_id");
        //分页查询
        Page<OrdinaryCourse> page = new Page<>(param.getPageNum() == null ? 1 : param.getPageNum(), param.getPageSize() == null ? 5 : param.getPageSize());
        ordinaryCourseMapper.selectPage(page,wrapper);
        //集合转换
        List<CoachOrdinaryCourseDTO> coachOrdinaryCourseDTOS = new ArrayList<>();
        if (page.getRecords()!=null&&page.getRecords().size()>0){
            for (OrdinaryCourse ordinaryCourse : page.getRecords()) {
                //对象转换
                CoachOrdinaryCourseDTO coachOrdinaryCourseDTO = BeanUtil.toBean(ordinaryCourse, CoachOrdinaryCourseDTO.class);
                //课程类型赋值
                Result<CourseTypeDTO> courseTypeDTOResult = courseClient.getCourseTypeById(ordinaryCourse.getCourseTypeId());
                if (courseTypeDTOResult.getCode()!=200) throw new CourseException(courseTypeDTOResult.getCode(),courseTypeDTOResult.getMessage());
                //获取数据
                CourseTypeDTO courseTypeDTO = courseTypeDTOResult.getData();
                //判断是否存在
                if (courseTypeDTO==null) throw new CourseException(CourseExceptionCode.COURSE_EXCEPTION_CODE_COURSE_TYPE_NOT_EXIST);
                coachOrdinaryCourseDTO.setCourseTypeName(courseTypeDTO.getCourseTypeName());
                //教练名称赋值
                Result<Coach> coachResult = coachClient.getCoachById(ordinaryCourse.getCoachId());
                if (coachResult.getCode()!=200) throw new CourseException(coachResult.getCode(),coachResult.getMessage());
                //获取数据
                Coach coach = coachResult.getData();
                //判断是否存在
                if (coach==null) throw new CourseException(CourseExceptionCode.COURSE_EXCEPTION_CODE_COACH_NOT_EXIST);
                coachOrdinaryCourseDTO.setCoachName(coach.getCoachName());
                //门店名称赋值
                Result<BusinessStoreDTO> businessStoreDTOResult = businessClient.selByBusinessStoreId(ordinaryCourse.getStoreId());
                if (businessStoreDTOResult.getCode()!=200) throw new CourseException(businessStoreDTOResult.getCode(),businessStoreDTOResult.getMessage());
                //获取数据
                BusinessStoreDTO businessStoreDTO = businessStoreDTOResult.getData();
                //判断是否存在
                if (businessStoreDTO==null) throw new CourseException(CourseExceptionCode.COURSE_EXCEPTION_CODE_BUSINESS_STORE_NOT_EXIST);
                coachOrdinaryCourseDTO.setStoreName(businessStoreDTO.getStoreName());
                //教室名称赋值
                Result<StoreClassroomByIdDTO> storeClassroomByIdDTOResult = businessClient.selNormalByStoreClassroomId(ordinaryCourse.getClassroomId());
                if (storeClassroomByIdDTOResult.getCode()!=200) throw new CourseException(storeClassroomByIdDTOResult.getCode(),storeClassroomByIdDTOResult.getMessage());
                //获取数据
                StoreClassroomByIdDTO storeClassroomByIdDTO = storeClassroomByIdDTOResult.getData();
                //判断是否存在
                if (storeClassroomByIdDTO==null) throw new CourseException(CourseExceptionCode.COURSE_EXCEPTION_CODE_CLASS_ROOM_NOT_EXIST);
                coachOrdinaryCourseDTO.setClassroomName(storeClassroomByIdDTO.getClassroomName());
                //状态赋值
                coachOrdinaryCourseDTO.setCourseState(ordinaryCourse.getCourseState()==0?"待开课":ordinaryCourse.getCourseState()==1?"已开课":ordinaryCourse.getCourseState()==2?"已取消":"已完成");
                //数据保存
                coachOrdinaryCourseDTOS.add(coachOrdinaryCourseDTO);
            }
        }
        //分页对象转换
        PageInfo pageInfo = BeanUtil.toBean(page, PageInfo.class);
        pageInfo.setPages(page.getPages());
        pageInfo.setRecords(coachOrdinaryCourseDTOS);
        return pageInfo;
    }

    /**
     * 统计该时间段普通课程已完成的总时长
     * @param param
     * @return
     */
    @Override
    public Integer amountOrdinaryCourseDuration(AmountOrdinaryCourseDurationParam param) {
        QueryWrapper<OrdinaryCourse> wrapper = new QueryWrapper<>();
        wrapper.ge("course_start_date",param.getStartTime());
        wrapper.le("course_end_date",param.getEndTime());
        wrapper.eq("store_id",param.getStoreId());
        wrapper.eq("course_state",CourseState.ORDINARY_COURSE_STATE_COMPLETE);
        //查询数据
        List<OrdinaryCourse> ordinaryCourses = ordinaryCourseMapper.selectList(wrapper);
        //准备一个参数 用于记录总时长
        Integer duration = 0;
        //判断是否存在
        if (ordinaryCourses!=null&&ordinaryCourses.size()>0){
            //遍历获取时长
            for (OrdinaryCourse ordinaryCours : ordinaryCourses) {
                duration += ordinaryCours.getCourseDuration();
            }
        }
        return duration;
    }

    /**
     * 普通课程当前预约人数减一
     * @param courseId
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void reduceCurrentCount(Integer courseId) {
        OrdinaryCourse ordinaryCourse = ordinaryCourseMapper.selectById(courseId);
        //判断是否存在
        if (ordinaryCourse==null) throw new CourseException(CourseExceptionCode.COURSE_EXCEPTION_CODE_ORDINARY_COURSE_NOT_EXIST);
        //判断普通课程是否异常
        if (ordinaryCourse.getCourseState()!=CourseState.ORDINARY_COURSE_STATE_WAIT) throw new CourseException(CourseExceptionCode.COURSE_EXCEPTION_CODE_ORDINARY_COURSE_STATE_ERROR);
        //判断当前人数是否已经等于零
        if (ordinaryCourse.getCurrentCount()<1) throw new CourseException(CourseExceptionCode.COURSE_EXCEPTION_CODE_CURRENT_COUNT_ZERO);
        //人数减一
        ordinaryCourse.setCurrentCount(ordinaryCourse.getCurrentCount()-1);
        ordinaryCourseMapper.updateById(ordinaryCourse);
    }
}
